package context.environ;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;

public class Keys
{
    
    private static Keys singleton = new Keys();
    
    public static Keys get()
    {
        return Keys.singleton;
    }
    
    private Keys()
    {
    }
    
    
    private static int NUM_KEYS = Keyboard.KEYBOARD_SIZE;
    
    public static int // Keyboard indices, of type: NAME_DESC
            Q, W, E, R, T, Y, U, I, O, P,
            A, S, D, F, G, H, J, K, L,
            Z, X, C, V, B, N, M,
            NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9, NUM_0,
            F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
            ESCAPE, TAB, ENTER, SPACE, 
            CTRL_L, CTRL_R, SHIFT_L, SHIFT_R, 
            ARROW_UP, ARROW_LEFT, ARROW_DOWN, ARROW_RIGHT, 
            NUMPAD_ENTER, NUMPAD_0, NUMPAD_1, NUMPAD_2, NUMPAD_3, NUMPAD_4, 
            NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9;
    
    
    private boolean[] mStateCur;
    
    private boolean[] mStatePrev;
    
    
    public void onStart()
    {
        this.initKeyIndices();
        
        this.mStateCur = new boolean[Keys.NUM_KEYS];
        this.mStatePrev = new boolean[Keys.NUM_KEYS];
        
        this.initKeyboard();
    }
    
    public void onTick()
    {
        for (int i = 0; i < Keys.NUM_KEYS; i++)
        {
            boolean isDown = Keyboard.isKeyDown(i);
            this.mStatePrev[i] = this.mStateCur[i];
            this.mStateCur[i] = isDown;
        }
    }
    
    public void onEnd()
    {
        Keyboard.destroy();
        this.mStateCur = null;
        this.mStatePrev = null;
    }
    
    
    public boolean isDown(final int aKey)
    {
        boolean isDown = this.mStateCur[aKey];
        return isDown;
    }
    
    public boolean isPressed(final int aKey)
    {
        boolean pressed = (this.mStateCur[aKey] && !this.mStatePrev[aKey]);
        return pressed;
    }
    
    public boolean isReleased(final int aKey)
    {
        boolean released = (!this.mStateCur[aKey] && this.mStatePrev[aKey]);
        return released;
    }
    
    
    private void initKeyboard()
    {
        Keyboard.enableRepeatEvents(true);
        try
        {
            Keyboard.create();
        }
        catch (LWJGLException e)
        {
            System.err.println(e);
            System.exit(1);
        }
    }
    
    private void initKeyIndices()
    {
        Keys.Q = Keyboard.KEY_Q;
        Keys.W = Keyboard.KEY_W;
        Keys.E = Keyboard.KEY_E;
        Keys.R = Keyboard.KEY_R;
        Keys.T = Keyboard.KEY_T;
        Keys.Y = Keyboard.KEY_Y;
        Keys.U = Keyboard.KEY_U;
        Keys.I = Keyboard.KEY_I;
        Keys.O = Keyboard.KEY_O;
        Keys.P = Keyboard.KEY_P;
        Keys.A = Keyboard.KEY_A;
        Keys.S = Keyboard.KEY_S;
        Keys.D = Keyboard.KEY_D;
        Keys.F = Keyboard.KEY_F;
        Keys.G = Keyboard.KEY_G;
        Keys.H = Keyboard.KEY_H;
        Keys.J = Keyboard.KEY_J;
        Keys.K = Keyboard.KEY_K;
        Keys.L = Keyboard.KEY_L;
        Keys.Z = Keyboard.KEY_Z;
        Keys.X = Keyboard.KEY_X;
        Keys.C = Keyboard.KEY_C;
        Keys.V = Keyboard.KEY_V;
        Keys.B = Keyboard.KEY_B;
        Keys.N = Keyboard.KEY_N;
        Keys.M = Keyboard.KEY_M;
        Keys.NUM_0 = Keyboard.KEY_0;
        Keys.NUM_1 = Keyboard.KEY_1;
        Keys.NUM_2 = Keyboard.KEY_2;
        Keys.NUM_3 = Keyboard.KEY_3;
        Keys.NUM_4 = Keyboard.KEY_4;
        Keys.NUM_5 = Keyboard.KEY_5;
        Keys.NUM_6 = Keyboard.KEY_6;
        Keys.NUM_7 = Keyboard.KEY_7;
        Keys.NUM_8 = Keyboard.KEY_8;
        Keys.NUM_9 = Keyboard.KEY_9;
        Keys.F1 = Keyboard.KEY_F1;
        Keys.F2 = Keyboard.KEY_F2;
        Keys.F3 = Keyboard.KEY_F3;
        Keys.F4 = Keyboard.KEY_F4;
        Keys.F5 = Keyboard.KEY_F5;
        Keys.F6 = Keyboard.KEY_F6;
        Keys.F7 = Keyboard.KEY_F7;
        Keys.F8 = Keyboard.KEY_F8;
        Keys.F9 = Keyboard.KEY_F9;
        Keys.F10 = Keyboard.KEY_F10;
        Keys.F11 = Keyboard.KEY_F11;
        Keys.F12 = Keyboard.KEY_F12;
        Keys.ESCAPE = Keyboard.KEY_ESCAPE;
        Keys.TAB = Keyboard.KEY_TAB;
        Keys.ENTER = Keyboard.KEY_RETURN;
        Keys.SPACE = Keyboard.KEY_SPACE;
        Keys.CTRL_L = Keyboard.KEY_LCONTROL;
        Keys.CTRL_R = Keyboard.KEY_RCONTROL;
        Keys.SHIFT_L = Keyboard.KEY_LSHIFT;
        Keys.SHIFT_R = Keyboard.KEY_RSHIFT;
        Keys.ARROW_UP = Keyboard.KEY_UP;
        Keys.ARROW_LEFT = Keyboard.KEY_LEFT;
        Keys.ARROW_RIGHT = Keyboard.KEY_RIGHT;
        Keys.ARROW_DOWN = Keyboard.KEY_DOWN;
        Keys.NUMPAD_ENTER = Keyboard.KEY_NUMPADENTER;
        Keys.NUMPAD_0 = Keyboard.KEY_NUMPAD0;
        Keys.NUMPAD_1 = Keyboard.KEY_NUMPAD1;
        Keys.NUMPAD_2 = Keyboard.KEY_NUMPAD2;
        Keys.NUMPAD_3 = Keyboard.KEY_NUMPAD3;
        Keys.NUMPAD_4 = Keyboard.KEY_NUMPAD4;
        Keys.NUMPAD_5 = Keyboard.KEY_NUMPAD5;
        Keys.NUMPAD_6 = Keyboard.KEY_NUMPAD6;
        Keys.NUMPAD_7 = Keyboard.KEY_NUMPAD7;
        Keys.NUMPAD_8 = Keyboard.KEY_NUMPAD8;
        Keys.NUMPAD_9 = Keyboard.KEY_NUMPAD9;
    }
    
}
